<template>
  <section class="home-container">
    <Master title="角色管理">
      <div slot="searchContent" class="search-content-slot">
        <Button
          type="info"
          icon="md-refresh"
          v-can:ViewRole
          :loading="searching"
          @click="searchByCondition"
          >刷新</Button
        >&nbsp;
        <Button
          v-can:AddRole
          type="primary"
          icon="md-add"
          @click="
            formData = {};
            modalVisible = true;
          "
          >添加角色</Button
        >
      </div>
      <div slot="paddingContent" v-can:ViewRole>
        <Table :columns="columns" :data="list">
          <!-- 操作 -->
          <template v-slot:action="{ row }">
            <Button
              v-can:EditRole
              type="primary"
              size="small"
              @click="
                formData = { ...row };
                modalVisible = true;
              "
              >编辑</Button
            >
            <Button
              v-can:DeleteRole
              type="error"
              size="small"
              class="lr5"
              :loading="deleting"
              @click="deleteRole(row)"
              >删除</Button
            >
            <Button
              v-can:AssignRoleRights
              type="info"
              size="small"
              :loading="gettingRoles"
              @click="assignRights(row)"
              >分配权限</Button
            >
          </template>
        </Table>
      </div>
    </Master>
    <!-- 模态框 -->
    <Modal
      v-can="['AddRole', 'EditRole']"
      :title="formData.Id ? '修改角色' : '添加角色'"
      v-model="modalVisible"
    >
      <Form
        :model="formData"
        :label-width="80"
        ref="formData"
        :rules="ruleInline"
      >
        <FormItem label="角色名称" prop="Name">
          <Input
            v-model.trim="formData.Name"
            :maxlength="20"
            placeholder="输入角色名称"
          ></Input>
        </FormItem>
      </Form>
      <div slot="footer">
        <Button @click="modalVisible = false">关闭</Button>
        <Button type="primary" @click="handleSubmit" :loading="saving"
          >保存</Button
        >
      </div>
    </Modal>
    <!-- 分配权限 -->
    <Modal title="分配权限" v-model="rightsVisible" v-can:AssignRoleRights>
      <Tree ref="tree" show-checkbox :data="menuList"></Tree>
      <div slot="footer">
        <Button @click="rightsVisible = false">关闭</Button>
        <Button type="primary" @click="confirmRights" :loading="saving"
          >保存</Button
        >
      </div>
    </Modal>
  </section>
</template>
<script>
import {
  AddRole,
  GetRoles,
  AddRights,
  GetRights,
  DeleteRole,
  UpdateRole,
} from "@/api/Rights.js";
import { mapState, mapActions, mapMutations } from "vuex";
export default {
  data() {
    return {
      /**
       * 要修改的角色
       */
      role: {},
      saving: false,
      /**
       * 获取角色中
       */
      gettingRoles: false,
      /**
       * 表单数据
       */
      formData: {
        Name: "",
      },
      /**
       * 菜单列表
       */
      menuList: [],
      /**
       * 修改对话框的属性
       */
      modalVisible: false,
      /**
       * 分配权限对话框是否显示
       */
      rightsVisible: false,
      /**
       * 表格列
       */
      columns: [
        {
          title: "角色名称",
          align: "center",
          key: "Name",
        },
        {
          title: "操作",
          width: 230,
          align: "center",
          slot: "action",
        },
      ],
      /**
       * 表单规则
       */
      ruleInline: {
        Name: [
          {
            required: true,
            message: "角色名称不能为空",
            trigger: "blur",
          },
          {
            min: 2,
            max: 20,
            message: "角色名称必须为2-20位",
            trigger: "blur",
          },
        ],
      },
    };
  },
  methods: {
    /**
     * 验证表单
     */
    async handleSubmit() {
      this.saving = true;
      try {
        const result = await this.$refs.formData.validate();
        if (!result) {
          return;
        }
        await (this.formData.Id
          ? UpdateRole(this.formData)
          : AddRole(this.formData.Name));
        this.$Message.success("角色保存成功");
        this.modalVisible = false;
        this.selectCondition();
      } catch (error) {
      } finally {
        this.saving = false;
      }
    },
    /**
     * 删除角色
     */
    async deleteRole(row) {
      try {
        await this.$confirm(
          `您确定要删除【${row.Name}】吗？删除后数据将无法恢复！`
        );
        this.deleting = true;
        await DeleteRole(row.Id);
        this.$Message.success("删除成功");
        this.selectCondition();
      } catch (error) {}
      this.deleting = false;
    },
    /**
     * 查询
     */
    async selectCondition() {
      if (!this.$validR("ViewRole")) {
        return;
      }
      try {
        this.searching = true;
        const result = await GetRoles();
        this.list = result;
      } catch (error) {}
      this.searching = false;
    },
    /**
     * 分配权限
     */
    async assignRights(row) {
      try {
        if (row.Id === this.user.RoleId) {
          await this.$confirm(
            "您要修改的角色权限跟您的角色一致，权限变动将会重新登录，您确定要继续吗？"
          );
        }
        this.gettingRoles = true;
        if (!this.menus.length) {
          await this.getMenus();
        }
        const menus = this.$deepClone(this.menus);
        const result = (await GetRights(row.Id)).map((c) => c.MenuId);
        +(function deep(source) {
          for (let item of source) {
            item.checked = result.includes(item.Id);
            item.children && deep(item.children);
          }
        })(menus);
        this.role = { ...row };
        this.menuList = menus;
        this.rightsVisible = true;
      } catch (error) {
      } finally {
        this.gettingRoles = false;
      }
    },
    /**
     * 提交权限
     */
    async confirmRights() {
      try {
        this.saving = true;
        const ids = this.$refs.tree.getCheckedNodes().map((c) => c.Id);
        await AddRights(this.role.Id, ids);
        this.$Message.success("权限分配成功");
        this.rightsVisible = false;
        if (this.role.Id === this.user.RoleId) {
          this.$exit();
        }
      } catch (error) {}
      this.saving = false;
    },
    ...mapMutations(["setUser"]),
    ...mapActions(["getMenus"]),
  },
  computed: {
    ...mapState(["menus", "user"]),
  },
  created() {
    this.selectCondition();
  },
  watch: {
    modalVisible(value) {
      value && this.$refs.formData.resetFields();
    },
  },
};
</script>